#include <iostream>
#include <pthread.h>
#include <cerrno>
#include <string.h>
#include <unistd.h>
#include <string>
#include <thread>
using namespace std;


int tickets = 1000;
pthread_mutex_t mutex;  //定义全局锁

void* routine(void* args)
{
    string name = static_cast<const char*> (args);
    //线程进行抢票
    while(true)
    {
       //加锁
       pthread_mutex_lock(&mutex);
       if(tickets > 0)  //有票继续抢
       {
          usleep(2000);//模拟线程抢票的等待时间
         cout<<name<<"get a ticket："<<tickets--<<endl;
         //解锁
         pthread_mutex_unlock(&mutex);
       }else
       { //没有票退出
            //break;
        //解锁
         pthread_mutex_unlock(&mutex);  //直接解锁退出，不用break--》没锁用break
       }

       usleep(1000); //模拟抢完一张票之后执行后续操作
    }  
    return nullptr;
}

int main()
{
    pthread_mutex_init(&mutex,nullptr);  //对锁进行初始化
    pthread_t td[4];  //定义线程标识符
    for(int i = 0;i < 4;i++)
    {
        char* name = new char[64];
        snprintf(name,64,"thread-%d",(i+1));
        pthread_create(td+i,nullptr,routine,name); //创建线程
    }
    
    //等待线程
    for(int i = 0;i < 4;i++)
    {
        int n = pthread_join(td[i],nullptr);  //无需返回值，传nullptr
        if(n != 0) 
        {
            cerr<<"error:"<<n<<strerror(n)<<endl;
        }
    }
     //使用完对锁进行销毁
     pthread_mutex_destroy(&mutex);
    return 0;
}




















// //int g_val  =100; //全局变量
// __thread int g_val  =100; //让每个线程对全局变量进行拷贝到线程栈

// string Hex(int id)
// {
//    char buffer[64];
//    snprintf(buffer,64,"0x%x",id);
//    return buffer;
// }

// void* ThreadRun(void* args)
// {
//     pthread_detach(pthread_self()); //自己分离自己
//     string name = static_cast<const char *> (args); //进行类型转化
//     int cnt = 5;
//     while(true)
//     {
//         //cout<<name<<":"<<cnt<<":"<<Hex(pthread_self())<<"&cnt:"<<&cnt<<endl;
//         cout<<name<<"g_val："<<g_val<<"，&g_val："<<&g_val<<endl;
//         sleep(1); //执行慢一点
//         //cnt--;
//     }
//     return  nullptr; 
// }

// int main()
// {
//     pthread_t thread_id1;  //定义线程标识符
//     pthread_t thread_id2;  //定义线程标识符
//     pthread_t thread_id3;  //定义线程标识符
//     pthread_create(&thread_id1,nullptr,ThreadRun,(void*)"thread 1");  //线程被创建的时候，谁先执行不确定！！
//     pthread_create(&thread_id2,nullptr,ThreadRun,(void*)"thread 2");  //线程被创建的时候，谁先执行不确定！！
//     pthread_create(&thread_id3,nullptr,ThreadRun,(void*)"thread 3");  //线程被创建的时候，谁先执行不确定！！
    
//     //线程等待
//     pthread_join(thread_id1,nullptr);
//     pthread_join(thread_id2,nullptr);
//     pthread_join(thread_id3,nullptr);

//     return 0;
// }
































// void run1()
// {
//     while(true)
//     {
//         cout<<"thread1 runing..."<<endl;
//         sleep(1);
//     }
// }

// void run2()
// {
//     while(true)
//     {
//         cout<<"thread2 runing..."<<endl;
//         sleep(1);
//     }
// }

// void run3()
// {
//     while(true)
//     {
//         cout<<"thread3 runing..."<<endl;
//         sleep(1);
//     }
// }


// int main()
// {
//     //创建线程
//     thread t1(run1);
//     thread t2(run2);
//     thread t3(run3);
//     //等待线程
//     t1.join();
//     t2.join();
//     t3.join();
    
//     return 0;
//}




//string Hex(int id)
// {
//    char buffer[64];
//    snprintf(buffer,64,"0x%x",id);
//    return buffer;
// }


// void* ThreadRun(void* args)
// {
//     pthread_detach(pthread_self()); //自己分离自己
//     string name = static_cast<const char *> (args); //进行类型转化
//     int cnt = 5;
//     while(cnt)
//     {
//         cout<<name<<":"<<cnt<<":"<<Hex(pthread_self())<<endl;
//         cnt--;
//         sleep(1); //执行慢一点
//     }
//     return  nullptr; 
// }

// int main()
// {
//     pthread_t thread_id;  //定义线程标识符
//     //创建子线程
//     pthread_create(&thread_id,nullptr,ThreadRun,(void*)"thread 1");
//     //sleep(1); //很重要，要让线程先分离，再等待
//     while(true)
//     {
//         cout<<"main thread :"<<Hex(pthread_self())<<"new thread id:"<<Hex(thread_id)<<endl;
//         sleep(1);
//     }
//     //线程分离
//     //pthread_detach(thread_id);
//     //线程等待
//     int n = pthread_join(thread_id,nullptr);
//     if( n != 0)  //线程等待-->错误
//     {
//         cerr<<"error: "<<n<<"："<<strerror(n)<<endl;
//     } 
//     //sleep(10);  //主线程过十秒后退出    
//     return 0;
// }